#include "i2c_master.h"

/* Definition of GPIOI2C constants */
#define GPIOI2C_ACK  				((uint8_t)1)
#define GPIOI2C_NACK 				((uint8_t)0)
#define I2CWRITE_MASK  				((uint8_t)0xFE)
#define I2CREAD_MASK   				((uint8_t)0x01)
/* Private variables ---------------------------------------------------------*/

#define SCL_STRETCH_TIMEOUT						1000000

/* Exported functions ---------------------------------------------------------*/

void GPIOI2C_Bus_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIOI2C_SCL_GPIO_CLK_ENABLE();
	GPIOI2C_SDA_GPIO_CLK_ENABLE();

	GPIO_InitStructure.GPIO_Pin = GPIOI2C_SCL_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

	GPIO_Init(GPIOI2C_SCL_GPIO_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIOI2C_SDA_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_Init(GPIOI2C_SDA_GPIO_PORT, &GPIO_InitStructure);

}


/**-----------------------------------------------------------------------
  * @brief  主机向芯片发送start指令
  * @param  无
  * @retval None
-------------------------------------------------------------------------*/
void I2C_Start(void)
{
	i2c_set_sda();
	i2c_set_scl();
	
	MY_DELAY_US(1);
	/*Bus free time(between Stop to Start time) tBUF>1.3us met by implement in stop() function*/
	i2c_clear_sda();
	MY_DELAY_US(1); 
	i2c_clear_scl();
	
}

/**-----------------------------------------------------------------------
  * @brief  主机向芯片发送restart指令
  * @param  无
  * @retval None
-------------------------------------------------------------------------*/
void I2C_reStart(void)
{
  /*ReStart condition */
	i2c_set_sda();
	MY_DELAY_US(1);  
	i2c_set_scl();
	MY_DELAY_US(1);  
	i2c_clear_sda();
	MY_DELAY_US(1); 
	i2c_clear_scl();
	MY_DELAY_US(1); 

}

/**-----------------------------------------------------------------------
  * @brief  主机向芯片发送stop指令
  * @param  无
  * @retval None
-------------------------------------------------------------------------*/
void I2C_Stop(void)
{
  /*Stop condition */
	i2c_clear_sda();
	MY_DELAY_US(1);  /*SU;STA*/
	i2c_set_scl();
	MY_DELAY_US(1);   /*tSU;STO*/
	i2c_set_sda();	
	MY_DELAY_US(1);/*tBUF>1.3us for Bus free time*/

}

/**-----------------------------------------------------------------------
  * @brief  主机向芯片发送一个字节
  * @param  要发送的字节
  * @retval 是否应答
-------------------------------------------------------------------------*/
uint8_t I2C_master_write(uint8_t b)
{
  	uint8_t mask = 0x80, ack=0;
	do
  	{	
		MY_DELAY_US(1);  /*tHD;DAT*/				
		sda_wr_control(b);	
		MY_DELAY_US(1);  /*tSU_DAT*/	
		i2c_set_scl();
		MY_DELAY_US(1);  /*nHigh*/
		i2c_clear_scl();			
  	}while ((mask>>=1) != 0);

	/* ACK slot checking */
	MY_DELAY_US(1); /*tHD;DAT*/		
	i2c_set_sda();/* Release SDA, waiting for tVD_ACK */
	MY_DELAY_US(1);  /*tSU_DAT*/
	i2c_set_scl();
	MY_DELAY_US(1); /*tHD;DAT*/		
	ack = (i2c_get_sda()? 0:1);	
	MY_DELAY_US(1);  /*nHigh*/
	i2c_clear_scl();
  	return (ack);
}

/**-----------------------------------------------------------------------
  * @brief  主机从芯片读取一个字节
  * @param  要发送给芯片的应答或非应答
  * @retval 读取到的一个字节数据
-------------------------------------------------------------------------*/
uint8_t I2C_master_read(uint8_t ack)
{ uint8_t mask = 0x80, b = 0;

	i2c_set_sda();									/*Release SDA*/

	do
	{
	 	MY_DELAY_US(1);	
	  	i2c_set_scl();
	  	MY_DELAY_US(1);
  		sda_rd_control(b);
	  	i2c_clear_scl();
	  	MY_DELAY_US(1);
	}while ((mask>>=1) != 0);

	/* ACK slot control */
	if(ack != 0) 
	{
		i2c_clear_sda();		/* SDA=0 for ACK*/
	}
	else
	{
		i2c_set_sda();		/* SDA=1 for NACK*/
	}	
	MY_DELAY_US(1);
	i2c_set_scl();
	MY_DELAY_US(1);
	i2c_clear_scl();
	MY_DELAY_US(1);

	return (b);
}
